package com.ygqh.baby.handler;

import com.ygqh.baby.ao.*;
import com.ygqh.baby.constant.Constant;
import com.ygqh.baby.model.BalanceDetailForTask;
import com.ygqh.baby.po.*;
import com.ygqh.baby.service.YgAgentInviteRecordService;
import com.ygqh.baby.service.YgAgentService;
import com.ygqh.baby.service.YgUserBalanceDetailService;
import com.ygqh.baby.service.YgUserService;
import com.ygqh.baby.service.task.YgBalanceTaskService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.ygqh.baby.service.task.YgBalanceTaskService.MINUS_ONE;

/**
 * 预收入处理器
 * （预收入明细对应订单明细）
 *
 * @Author: sunshuo
 * @Date: 2019/4/30 15:02
 * @Version: 1.0
 */
@Component
public class PreBalanceHandler {

	@Autowired
	private YgUserBalanceDetailService ygUserBalanceDetailService;
	@Autowired
	private YgUserService ygUserService;
	@Autowired
	private YgBalanceTaskService ygBalanceTaskService;
	@Autowired
	private YgAgentInviteRecordService ygAgentInviteRecordService;
	@Autowired
	private YgAgentService ygAgentService;

	/**
	 * 计算订单预收入
	 * （根据销售平台把订单拆分为壹果订单和壹家店订单，返利逻辑分开处理）
	 *
	 * @param orderList 订单信息
	 * @return 预收入明细集
	 * @Date: 2019/05/08
	 * @Version: 1.0
	 */
	public List<YgUserBalanceDetail> doOrderPreBalance(List<YgOrder> orderList) {
		List<YgUserBalanceDetail> detailList = new ArrayList<>();
		if (CollectionUtils.isNotEmpty(orderList)) {
			// 壹果订单
			List<YgOrder> orderListAtYiigoo = orderList.stream()
					.filter(o -> !Constant.YIJIADIAN_PLATFORM_NO.equals(o.getPlatformNo()))
					.collect(Collectors.toList());
			detailList.addAll(doOrderPreBalanceByYiigoo(orderListAtYiigoo));
			// 壹家店订单
			List<YgOrder> orderListAtYijiadian = orderList.stream()
					.filter(o -> Constant.YIJIADIAN_PLATFORM_NO.equals(o.getPlatformNo()))
					.collect(Collectors.toList());
			detailList.addAll(doOrderPreBalanceByYijiadian(orderListAtYijiadian));
		}
		return detailList;
	}

	/**
	 * 计算订单预收入
	 * (不再区分销售平台，
	 * 	返利条件: 以【用户实际支付金额+成长基金抵扣】为基准，以代理与粉丝绑定关系为途径；
	 * 	返利规则:
	 * 	 1、壹果商城女王在壹果商城下单，无任何返利；
	 * 	 2、代理下单，自己有消费奖励，返利比例为100%佣金；
	 * 	 3、代理下单，推荐人为代理时有分享奖励，返利比例为30%佣金；
	 * 	 4、代理的粉丝下单，代理有分享奖励，返利比例为100%佣金；
	 * 	 5、代理的粉丝下单，代理的推荐人为代理时有推荐奖励，返利比例为30%佣金；)
	 *
	 * 	更新：代理本身设置等级比例 levelRate，实际返利 = 计算后佣金 * levelRate
	 *
	 * @param orderList 订单信息
	 * @return 预收入明细集
	 * @Date: 2019/06/25
	 * @Version: 1.1
	 */
	public List<YgUserBalanceDetail> doOrderPreBalanceNotSpitPlatform(List<YgOrder> orderList) {
		List<YgUserBalanceDetail> detailList = new ArrayList<>();
		if (CollectionUtils.isEmpty(orderList)) {
			return detailList;
		}
		for (YgOrder order : orderList) {
			// 0元订单也记入返利记录，以表示该订单符合返利规则
			/*if (order.getTotalPrice().add(order.getAccountPrice()).compareTo(BigDecimal.ZERO) <= 0) {
				// 0元订单不参与返利
				continue;
			}*/
			if (!Constant.YIIGOO_PLATFORM_NO.equals(order.getPlatformNo())
					&& !Constant.YIJIADIAN_PLATFORM_NO.equals(order.getPlatformNo())) {
				// 非壹果商城壹家店订单 不参与返利
				continue;
			}
			YgUser user = ygUserService.findById(order.getUserId()); // 下单用户
			if (user == null) {
				// 非常规用户下单
				continue;
			}
			if (Constant.YIIGOO_PLATFORM_NO.equals(order.getPlatformNo())
					&& ygUserService.isVipNew(user.getId(), Constant.YIIGOO_PLATFORM_NO)) {
				// 1、壹果商城订单，女王下单不给予任何返利
				continue;
			}
			YgAgent currUserAgent = ygAgentService.findValidByUserId(user.getId(), UserType.UserAgent);
			if (user.isUserAgent() && ablePreBalance(currUserAgent, order.getPaidTime())) {
				processOrderDetailPriceForShare(order, currUserAgent.getLevelRate());
				// 2、代理下单，自己有消费奖励，返利比例为100%佣金；
				this.setPreBalanceDetailList(detailList, order, RebateType.Reward,
						OperationType.Reward, user.getId(), "currentUser");
			}
			YgUser inviteUser = getInviteUserForPreBalance(order.getUserId(), order.getPaidTime()); // 推荐人
			if (inviteUser == null) {
				// 非常规推荐人 或 下单时间在邀请时间之前 或 信息异常
				continue;
			}
			YgAgent inviteUserAgent = ygAgentService.findValidByUserId(inviteUser.getId(), UserType.UserAgent);
			if (inviteUser.isUserAgent() && ablePreBalance(inviteUserAgent, order.getPaidTime())) {
				// 3、代理下单，推荐人为代理时有分享奖励，返利比例为30%佣金；
				// 4、代理的粉丝下单，代理有分享奖励，返利比例为100%佣金；
				BigDecimal priceRate = inviteUserAgent.getLevelRate();
				if (user.isUserAgent()) {
					priceRate = priceRate.multiply(BigDecimal.valueOf(0.3));
				}
				processOrderDetailPriceForShare(order,priceRate);
				this.setPreBalanceDetailList(detailList, order, RebateType.Share,
						OperationType.Share, inviteUser.getId(), "foreverUser");
				if (!user.isUserAgent()) {
					YgUser crossInviteUser = getInviteUserForPreBalance(inviteUser.getId(), order.getPaidTime()); // 跨级推荐人
					if (crossInviteUser == null) {
						continue;
					}
					YgAgent crossInviteUserAgent = ygAgentService.findValidByUserId(crossInviteUser.getId(), UserType.UserAgent);
					if (crossInviteUser.isUserAgent() && ablePreBalance(crossInviteUserAgent, order.getPaidTime())) {
						// 5、代理的粉丝下单，代理的推荐人为代理时有推荐奖励，返利比例为30%佣金；
						processOrderDetailPriceForShare(order,
								inviteUserAgent.getLevelRate().multiply(BigDecimal.valueOf(0.3)));
						this.setPreBalanceDetailList(detailList, order, RebateType.Forever,
								OperationType.Forever, crossInviteUser.getId(), "crossForeverUser");
					}
				}
			}
		}
		return detailList;
	}

	/**
	 * 是否有资格算预收入
	 * 1、代理
	 * 2、成为代理时间在订单时间之前
	 * 3、返利等级比例大于0
	 *
	 * @param agentInfo 代理信息
	 * @param orderTime 订单时间
	 * @return
	 */
	private boolean ablePreBalance(YgAgent agentInfo, Date orderTime) {
		return agentInfo != null
				&& orderTime.after(agentInfo.getCheckTime())
				&& (agentInfo.getLevelRate().compareTo(BigDecimal.ZERO) > 0);
	}

	public void processOrderDetailPriceForShare(YgOrder order, BigDecimal priceRate) {
		if (priceRate.compareTo(BigDecimal.ONE) == 0) {
			return;
		}
		order.getOrderDetail().forEach(o -> {
			o.setRealPrice(o.getRealPrice().multiply(priceRate)
					.setScale(2, BigDecimal.ROUND_HALF_UP));
			if (o.getAccountPrice() == null) {
				o.setAccountPrice(BigDecimal.ZERO);
			} else {
				o.setAccountPrice(o.getAccountPrice().multiply(priceRate)
						.setScale(2, BigDecimal.ROUND_HALF_UP));
			}
		});
	}

	/**
	 * 计算壹果平台订单预收入
	 * 规则：
	 * 1、代理下单，仅自己有分享奖励，返利比例为商品的分享比例；
	 * 2、女王下单，自己有消费奖励，返利比例为固定值2%；
	 * 3、代理分享给非代理用户，代理用户有分享奖励，返利比例为商品的分享比例；
	 *
	 * @param orderList 订单信息
	 * @return 预收入明细集
	 * @Date: 2019/05/08
	 * @Version: 1.0
	 */
	private List<YgUserBalanceDetail> doOrderPreBalanceByYiigoo(List<YgOrder> orderList) {
		List<YgUserBalanceDetail> detailList = new ArrayList<>();
		if (CollectionUtils.isEmpty(orderList)) {
			return detailList;
		}
		for (YgOrder order : orderList) {
			if (order.getTotalPrice().compareTo(BigDecimal.ZERO) == 0) {
				// 0元订单不参与返利
				continue;
			}
			YgUser user = ygUserService.findById(order.getUserId()); // 下单用户
			if (user == null) {
				continue;
			}
			if (user.isUserAgent()) {
				// 1、代理下单，仅自己有分享奖励，返利比例为商品的分享比例；
				ygBalanceTaskService.setPreBalanceDetailList(detailList, order, RebateType.Share,
						OperationType.Share, user.getId(), "currentUser");
				continue;
			}
			if (ygUserService.isVipNew(user.getId(), Constant.YIIGOO_PLATFORM_NO)) {
				// 2、女王下单，自己有消费奖励，返利比例为固定值2%；
				ygBalanceTaskService.setPreBalanceDetailList(detailList, order, RebateType.Reward,
						OperationType.Reward, user.getId(), "currentUser");
			}
			YgUser shareUser = ygUserService.findBySourceCode(order.getSourceCode()); // 分享用户
			if (shareUser != null && shareUser.isUserAgent()) {
				// 3、代理分享给非代理用户，代理用户有分享奖励，返利比例为商品的分享比例；
				ygBalanceTaskService.setPreBalanceDetailList(detailList, order, RebateType.Share,
						OperationType.Share, shareUser.getId(), "shareUser");
			}
		}
		return detailList;
	}

	/**
	 * 计算壹家店平台订单预收入
	 * 规则：（佣金比例为商品的分享比例）
	 * 1、代理下单，自己有消费奖励，返利比例为100%佣金；
	 * 2、代理下单，推荐人为代理时有分享奖励，返利比例为30%佣金；
	 * 3、代理的粉丝下单，代理有分享奖励，返利比例为100%佣金；
	 * 4、代理的粉丝下单，代理的推荐人为代理时有推荐奖励，返利比例为30%佣金；
	 *
	 * @param orderList 订单信息
	 * @return 预收入明细集
	 * @Date: 2019/05/08
	 * @Version: 1.0
	 */
	private List<YgUserBalanceDetail> doOrderPreBalanceByYijiadian(List<YgOrder> orderList) {
		List<YgUserBalanceDetail> detailList = new ArrayList<>();
		if (CollectionUtils.isEmpty(orderList)) {
			return detailList;
		}
		for (YgOrder order : orderList) {
			if (order.getTotalPrice().compareTo(BigDecimal.ZERO) == 0) {
				// 0元订单不参与返利
				continue;
			}
			YgUser user = ygUserService.findById(order.getUserId()); // 下单用户
			if (user == null) {
				continue;
			}
			if (user.isUserAgent()) {
				// 1、代理下单，自己有消费奖励，返利比例为100%佣金；
				ygBalanceTaskService.setPreBalanceDetailList(detailList, order, RebateType.Reward,
						OperationType.Reward, user.getId(), "currentUser");
			}
			YgUser inviteUser = getInviteUserForPreBalance(order.getUserId(), order.getPaidTime()); // 推荐人
			if (inviteUser != null && inviteUser.isUserAgent()) {
				// 2、代理下单，推荐人为代理时有分享奖励，返利比例为30%佣金；
				// 3、代理的粉丝下单，代理有分享奖励，返利比例为100%佣金；
				if (user.isUserAgent()) {
					order.getOrderDetail().forEach(o ->
							o.setSalePrice(o.getSalePrice().multiply(BigDecimal.valueOf(0.3))
									.setScale(2, BigDecimal.ROUND_HALF_UP)));
				}
				ygBalanceTaskService.setPreBalanceDetailList(detailList, order, RebateType.Share,
						OperationType.Share, inviteUser.getId(), "foreverUser");
				if (!user.isUserAgent()) {
					YgUser crossInviteUser = getInviteUserForPreBalance(inviteUser.getId(), order.getPaidTime()); // 跨级推荐人
					if (crossInviteUser != null && crossInviteUser.isUserAgent()) {
						// 4、代理的粉丝下单，代理的推荐人为代理时有推荐奖励，返利比例为30%佣金；
						order.getOrderDetail().forEach(o ->
								o.setSalePrice(o.getSalePrice().multiply(BigDecimal.valueOf(0.3))
										.setScale(2, BigDecimal.ROUND_HALF_UP)));
						ygBalanceTaskService.setPreBalanceDetailList(detailList, order, RebateType.Forever,
								OperationType.Forever, crossInviteUser.getId(), "crossForeverUser");
					}
				}
			}
		}
		return detailList;
	}

	/**
	 * 壹家店获取上级推荐人
	 *
	 * @param userId 用户id
	 * @param orderTime 订单时间
	 * @return 上级推荐人
	 */
	private YgUser getInviteUserForPreBalance(Long userId, Date orderTime) {
		YgAgentInviteRecord record = ygAgentInviteRecordService.findRecordForYijiandian(userId);
		if (record != null && orderTime.after(record.getReceiveTime())) {
			return ygUserService.findById(record.getUserId());
		}
		return null;
	}

	/**
	 * 计算退货预收入
	 * （以退货明细对应订单明细的占比，分摊下单预收入）
	 *
	 * @param returnList 退货单信息
	 * @param orderPreBalance 已计算出的订单预收入（兼容预收入任务间隔时间内做退款）
	 * @return 预收入明细集
	 * @Date: 2019/05/08
	 * @Version: 1.0
	 */
	public List<YgUserBalanceDetail> doReturnPreBalance(List<YgReturnOrder> returnList,
														List<YgUserBalanceDetail> orderPreBalance) {
		List<YgUserBalanceDetail> returnBalanceList = new ArrayList<>();
		if (CollectionUtils.isEmpty(returnList)) {
			return returnBalanceList;
		}
		Map<String, List<YgUserBalanceDetail>> collect = new HashMap<>();
		if (CollectionUtils.isNotEmpty(orderPreBalance)) {
			collect.putAll(orderPreBalance.stream().collect(Collectors.groupingBy(YgUserBalanceDetail::getOrderId)));
		}
		returnList.forEach(ro ->
				returnBalanceList.addAll(
					doReturnPreBalanceByReturnOrder(ro, collect.get(ro.getOrderId().toString()))));
		return returnBalanceList;
	}

	private List<YgUserBalanceDetail> doReturnPreBalanceByReturnOrder(YgReturnOrder ro,
																	  List<YgUserBalanceDetail> orderPreBalance) {
		List<YgUserBalanceDetail> returnBalanceList = new ArrayList<>();
		// 获取当前订单的所有预收入
		List<YgUserBalanceDetail> ubds =
				ygUserBalanceDetailService.findDetailByOrderDetail(BalanceType.PreIncome, null,
						null, ro.getOrderId().toString(), null);
		if (CollectionUtils.isEmpty(ubds)) {
			if (CollectionUtils.isEmpty(orderPreBalance)) {
				return returnBalanceList;
			}
			ubds = orderPreBalance;
		}
		// 按照明细分组
		Map<Long, List<YgUserBalanceDetail>> map = ubds.stream()
				.collect(Collectors.groupingBy(YgUserBalanceDetail::getOrderDetailId));
		ro.getReturnOrderDetails().forEach(rod -> {
			// 退差价不退返利
			if (map.containsKey(rod.getOrderDetailId()) && rod.getAmount() > 0) {
				returnBalanceList.addAll(doReturnPreBalanceByReturnDetail(rod, map.get(rod.getOrderDetailId())));
			}
		});
		return returnBalanceList;
	}

	private List<YgUserBalanceDetail> doReturnPreBalanceByReturnDetail(YgReturnOrderDetail rod,
														 List<YgUserBalanceDetail> userBalanceDetails) {
		List<YgUserBalanceDetail> returnBalanceList = new ArrayList<>();
		// 按照返利类型分组
		Map<RebateType, List<YgUserBalanceDetail>> collect = userBalanceDetails.stream()
				.collect(Collectors.groupingBy(YgUserBalanceDetail::getRebateType));
		collect.forEach((rebateType, ygUserBalanceDetails) ->
				returnBalanceList.addAll(doReturnPreBalanceByRebateType(rod, rebateType, ygUserBalanceDetails)));
		return returnBalanceList;
	}

	private List<YgUserBalanceDetail> doReturnPreBalanceByRebateType(YgReturnOrderDetail rod, RebateType rebateType,
														 List<YgUserBalanceDetail> userBalanceDetails) {
		List<YgUserBalanceDetail> returnBalanceList = new ArrayList<>();
		Map<Long, List<YgUserBalanceDetail>> collect = userBalanceDetails.stream()
				.collect(Collectors.groupingBy(YgUserBalanceDetail::getUserId));
		collect.forEach((userId, details) ->
				returnBalanceList.add(doReturnPreBalanceByUserId(rod, rebateType, userId, details)));
		return returnBalanceList;
	}

	private YgUserBalanceDetail doReturnPreBalanceByUserId(YgReturnOrderDetail rod, RebateType rebateType, Long userId,
														   List<YgUserBalanceDetail> userBalanceDetails) {
		YgUserBalanceDetail detail = userBalanceDetails.get(0);
		List<YgUserBalanceDetail> returned =
				ygUserBalanceDetailService.findByOrderDetailId(BalanceType.PreIncome, rebateType,
						userId, "return", rod.getOrderDetailId());
		BigDecimal incomePrice = detail.getIncomePayPrice();
		BigDecimal orderPrice = detail.getOrderPrice();
		BigDecimal currentOrderPrice = getSkuSharePrice(orderPrice, rod.getQuantity(), rod.getAmount());
		BigDecimal currentIncomePrice = currentOrderPrice.multiply(detail.getCommissionRate())
				.multiply(MINUS_ONE).setScale(1, BigDecimal.ROUND_HALF_UP);
		if (CollectionUtils.isNotEmpty(returned)) {
			for (YgUserBalanceDetail bd : returned) {
				incomePrice = incomePrice.add(bd.getIncomePayPrice());
				orderPrice = orderPrice.subtract(bd.getOrderPrice());
			}
		}
		if (currentOrderPrice.compareTo(orderPrice) >= 0) {
			currentOrderPrice = orderPrice;
			currentIncomePrice = incomePrice.multiply(MINUS_ONE);
		}
		YgUserBalanceDetail clone = detail.clone();
		clone.setOrderPrice(currentOrderPrice);
		clone.setIncomePayPrice(currentIncomePrice);
		clone.setOrderId(rod.getReturnCode());
		clone.setOperationType(OperationType.Return);
		clone.setOperation(OperationType.Return.getTitle());
		clone.setCreateTime(new Date());
		return clone;
	}

	private BigDecimal getSkuSharePrice(BigDecimal itemPrice, Long totalAmount, Long subAmount) {
		if (itemPrice != null) {
			if (totalAmount.compareTo(subAmount) > 0) {
				return itemPrice.divide(new BigDecimal(totalAmount)).multiply(new BigDecimal(subAmount));
			} else {
				return itemPrice;
			}
		}
		return null;
	}

	private void setPreBalanceDetailList(List<YgUserBalanceDetail> detailList, YgOrder order, RebateType rebateType,
										OperationType operationType, Long userId, String createBy) {
		List<BalanceDetailForTask> detailModel = preBalancePretreatment(order);
		List<YgUserBalanceDetail> shareUserDetails =
				ygBalanceTaskService.getPreBalanceDetailList(detailModel, rebateType, operationType, userId, createBy,
						order.getPlatformNo());
		detailList.addAll(shareUserDetails);
	}

	public List<BalanceDetailForTask> preBalancePretreatment(YgOrder order) {
		List<BalanceDetailForTask> list = null;
		for (YgOrderDetail detail : order.getOrderDetail()) {
			if (PromotionType.ManZeng.equals(detail.getPromotionType())) {
				// 赠品不参与返利，
				continue;
			}
			// 0元商品也记入返利记录，以表示该商品参与了返利
			/*if (detail.getSalePrice().compareTo(BigDecimal.ZERO) <= 0) {
				continue;
			}*/
			// 返利基准金额（实际支付+成长基金抵扣）
			BigDecimal orderSharePrice = detail.getRealPrice().add(detail.getAccountPrice());
			BalanceDetailForTask bd = new BalanceDetailForTask(detail.getId(), detail.getSupplierId(),
					order.getOrderId().toString(), orderSharePrice, detail.getProductName(),
					detail.getShareRate(), detail.getShareRate());
			if (list == null) {
				list = new ArrayList<>();
			}
			list.add(bd);
		}
		return list;
	}

	/**
	 * 拼团失败，退预收入
	 *
	 * @param orderId 拼团订单编号
	 * @param returnCodeListByComplete 退款已完成 退单号
	 * @throws
	 */
	public List<YgUserBalanceDetail> doCancelGroupOrder(Long orderId, List<String> returnCodeListByComplete) {
		List<YgUserBalanceDetail> returnBalanceList = new ArrayList<>();

		// 获取当前订单的所有预收入
		List<YgUserBalanceDetail> balanceDetailListForOrder =
				ygUserBalanceDetailService.findDetailByOrderDetail(BalanceType.PreIncome, null,
						null, orderId.toString(), null);
		if (CollectionUtils.isEmpty(balanceDetailListForOrder)) {
			return returnBalanceList;
		}
		Map<Long, List<YgUserBalanceDetail>> detailForOrderMap = balanceDetailListForOrder.stream().
				collect(Collectors.groupingBy(YgUserBalanceDetail::getOrderDetailId));
		Map<Long, List<YgUserBalanceDetail>> detailForReturnMap = new HashMap<>();
		if (CollectionUtils.isNotEmpty(returnCodeListByComplete)) {
			// 获取所有退单的预收入
			List<YgUserBalanceDetail> balanceDetailListForReturn = ygUserBalanceDetailService.
					selectBalanceDetailByOrderId(BalanceType.PreIncome, null, null,
							returnCodeListByComplete, null);
			if (CollectionUtils.isNotEmpty(balanceDetailListForOrder)) {
				// 按原订单明细分组
				detailForReturnMap.putAll(balanceDetailListForReturn.stream().
						collect(Collectors.groupingBy(YgUserBalanceDetail::getOrderDetailId)));
			}
		}
		detailForOrderMap.forEach((orderDetailId, detailForOrderList) ->
				returnBalanceList.addAll(
						doCancelGroupOrderByOdId(detailForOrderList, detailForReturnMap.get(orderDetailId))));
		return returnBalanceList;
	}

	private List<YgUserBalanceDetail> doCancelGroupOrderByOdId(List<YgUserBalanceDetail> detailForOrder,
															   List<YgUserBalanceDetail> detailForReturn) {
		Map<RebateType, List<YgUserBalanceDetail>> collect = detailForOrder.stream().
				collect(Collectors.groupingBy(YgUserBalanceDetail::getRebateType));
		Map<RebateType, List<YgUserBalanceDetail>> collect2 = new HashMap<>();
		if (CollectionUtils.isNotEmpty(detailForReturn)) {
			collect2.putAll(detailForReturn.stream().
					collect(Collectors.groupingBy(YgUserBalanceDetail::getRebateType)));
		}
		List<YgUserBalanceDetail> returnBalanceList = new ArrayList<>();
		collect.forEach((rebateType, ygUserBalanceDetails) ->
				returnBalanceList.addAll(
					doCancelGroupOrderByRbType(ygUserBalanceDetails, collect2.get(rebateType))));
		return returnBalanceList;
	}

	private List<YgUserBalanceDetail> doCancelGroupOrderByRbType(List<YgUserBalanceDetail> detailForOrder,
															   List<YgUserBalanceDetail> detailForReturn) {
		Map<Long, List<YgUserBalanceDetail>> collect = detailForOrder.stream().
				collect(Collectors.groupingBy(YgUserBalanceDetail::getUserId));
		Map<Long, List<YgUserBalanceDetail>> collect2 = new HashMap<>();
		if (CollectionUtils.isNotEmpty(detailForReturn)) {
			collect2.putAll(detailForReturn.stream().
					collect(Collectors.groupingBy(YgUserBalanceDetail::getUserId)));
		}
		List<YgUserBalanceDetail> returnBalanceList = new ArrayList<>();
		collect.forEach((userId, ygUserBalanceDetails) ->
				returnBalanceList.add(
					doCancelGroupOrderByUserId(ygUserBalanceDetails.get(0), collect2.get(userId))));
		return returnBalanceList;
	}

	private YgUserBalanceDetail doCancelGroupOrderByUserId(YgUserBalanceDetail detailForOrder,
														   List<YgUserBalanceDetail> detailForReturn) {
		BigDecimal incomePrice = detailForOrder.getIncomePayPrice();
		BigDecimal orderPrice = detailForOrder.getOrderPrice();
		if (CollectionUtils.isNotEmpty(detailForReturn)) {
			for (YgUserBalanceDetail bd : detailForReturn) {
				incomePrice = incomePrice.add(bd.getIncomePayPrice());
				orderPrice = orderPrice.subtract(bd.getOrderPrice());
			}
		}
		YgUserBalanceDetail clone = detailForOrder.clone();
		clone.setOrderPrice(orderPrice);
		clone.setIncomePayPrice(incomePrice.multiply(MINUS_ONE));
		clone.setOrderId(detailForOrder.getOrderId());
		clone.setOperationType(OperationType.CancelOrder);
		clone.setOperation(OperationType.CancelOrder.getTitle());
		clone.setCreateTime(new Date());
		return clone;
	}
}
